package fixture;

import java.io.IOException;
import java.net.InetAddress;
import java.sql.SQLException;

import vcp.client.exceptions.EmptyRequestException;
import vcp.client.request.CustomerCheckoutRequest;
import vcp.client.request.Request;
import vcp.enums.SiteEnum;
import vcp.server.DBAdapter;
import vcp.server.utility.timedecision.TimeDecisionMinute;
import clientserver.DummyServer;
import clientserver.DummyUIRootModel;
import fit.ActionFixture;

/**
 * 
 * @author VCP team
 * 
 *         <p>
 *         This class is responsible for testing the correct functionality on
 *         when user comes late to his ordered parking place and gets fined
 *         because of it
 *         </p>
 */
public class LateArrival extends ActionFixture
{
	private DummyServer server;
	private DummyUIRootModel client;

	private final int customerID;
	private final int carID;

	private final SiteEnum siteEnum;
	private String response;

	/**
	 * Constructor
	 */
	public LateArrival()
	{
		super();
		this.customerID = 312345680;
		this.siteEnum = SiteEnum.SITE_5;
		this.carID = 3245638;
	}

	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Customer check out
	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * sends an a check out request to server
	 */
	public void customerCheckOutWithFineDelay()
	{
		this.sendToServer(new CustomerCheckoutRequest(this.carID, this.siteEnum));
		this.client.waitForResponse();

		this.response = (String) this.client.getResponse().getData();
	}

	/**
	 * 
	 * @return message received from server due-to check out
	 */
	public String wasFineDelay()
	{
		return this.response;
	}

	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// private methods
	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 * send the {@link Request} to server via client
	 * 
	 * @param request
	 */
	private void sendToServer(Request request)
	{
		try
		{
			this.client.registerAndSendRequest(request, null);
		}
		catch (EmptyRequestException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Setup
	// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 * Initialization of Late arrival test
	 */
	public void setUp()
	{
		try
		{
			this.server = new DummyServer(5555, new TimeDecisionMinute());
			this.server.listen();

			Thread.sleep(1000);

			this.client = new DummyUIRootModel();
			this.client.connectToServer(InetAddress.getLocalHost().getHostAddress(), 5555);

			Thread.sleep(1000);
			System.out.println("up");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * DB modification according to the test requirements
	 */
	public void dbChange()
	{
		String subscriberActualArrivalUpdate = "UPDATE `vcp`.`cars` SET `arrivedTime`='2013-12-31 23:40:00' " + "WHERE `carID`='3245638' and`subscriptionID`='22' and`customerID`='" + this.customerID
				+ "';";
		String subscriberRegisteredArrivalUpdate = "UPDATE `vcp`.`subscriptions` SET `arrivalDate`='2013-12-31 23:00:00' WHERE `subscriptionID`='22' and`customerID`='312345680';";

		String[] sqls = new String[]
		{ subscriberActualArrivalUpdate, subscriberRegisteredArrivalUpdate };

		for (String string : sqls)
		{
			try
			{
				DBAdapter.getAdapter().refresh(string);
			}
			catch (SQLException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * Restoring DB previous to test
	 */
	public void dbCleanUp()
	{
		String subscriptionRemoveFromHistory = "DELETE FROM `vcp`.`subscriptionhistory` WHERE `subscriptionID`='22' and`customerID`='312345680';";
		String restoreSubscription = "INSERT INTO `vcp`.`subscriptions` VALUES (22,312345680,\"Site 5\",\"Order Ahead Customer\",\"2013-12-18 15:23:26\",\"2014-01-18 04:01:27\",\"2014-01-01 00:00:00\",\"2014-01-01 00:00:00\");";
		String restoreCar = "INSERT INTO `vcp`.`cars` VALUES (3245638,22,312345680,0,\"2001-01-01 00:00:00\",\"2001-01-01 00:00:00\");";

		String restoreCustomerDetails = "UPDATE `vcp`.`customer` SET `bussinessClass`='1', `balance`='800' WHERE `customerID`='312345680';";

		String restoreSiteReserved = "UPDATE `vcp`.`site` SET `occupiedLots`='1' WHERE `siteID`='5';";
		String restoreLotReserved = "UPDATE `vcp`.`lot` SET `status`='Occupied', `carID`='3245638', `reservedBySubscription`='2' WHERE `lotFloor`='1' and`lotRow`='1' and`lotColumn`='1' and`siteID`='5';";

		String[] sqlStatements = new String[]
		{ subscriptionRemoveFromHistory, restoreSubscription, restoreCar, restoreSiteReserved, restoreLotReserved, restoreCustomerDetails };

		for (String string : sqlStatements)
		{
			try
			{
				DBAdapter.getAdapter().refresh(string);
			}
			catch (SQLException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * kill test initialization
	 */
	public void tearDown()
	{
		try
		{
			this.client.closeConnection();
			this.server.stopListening();
			this.server.close();

			this.client = null;
			this.server = null;
			System.out.println("down");
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
